package client

import (
	"fmt"
	"github.com/gorilla/websocket"
	"html3/internal/syserror"
	"sync"
)

// WsClient 结构体代表一个WebSocket客户端
type WsClient struct {
	ClientId  string
	GroupName string
	Client    *websocket.Conn
}
type GroupManager interface {
	Set(groupName, clientId string, client *websocket.Conn) error
	Get(groupName string) ([]*websocket.Conn, error)
	Del(clientId string) error
}
type GroupClients struct {
	Groups      map[string][]*WsClient
	Mu          sync.RWMutex
	ClientGroup map[string]string // clientId到groupName的映射
}

func NewGroupClients() *GroupClients {
	return &GroupClients{
		Groups:      make(map[string][]*WsClient),
		ClientGroup: make(map[string]string),
	}
}
func (gc *GroupClients) withLock(f func()) {
	gc.Mu.Lock()
	defer gc.Mu.Unlock()
	f()
}

func (gc *GroupClients) withLockR(f func()) {
	gc.Mu.RLock()
	defer gc.Mu.RUnlock()
	f()
}

func (gc *GroupClients) Set(groupName, clientId string, client *websocket.Conn) error {
	gc.withLock(func() {

		// 检查clientId是否已存在
		if _, exists := gc.ClientGroup[clientId]; exists {
			return
		}

		// 创建新的WsClient实例
		wsClient := &WsClient{
			ClientId:  clientId,
			GroupName: groupName,
			Client:    client,
		}
		// 添加客户端到组
		gc.Groups[groupName] = append(gc.Groups[groupName], wsClient)

		// 更新clientId到groupName的映射
		gc.ClientGroup[clientId] = groupName

	})

	return nil
}

func (gc *GroupClients) Get(groupName string) ([]*websocket.Conn, error) {
	// 获取组中的所有客户端连接
	var conns []*websocket.Conn
	gc.withLockR(func() {
		// 检查组是否存在
		if _, exists := gc.Groups[groupName]; !exists {
			return
		}

		for _, client := range gc.Groups[groupName] {
			conns = append(conns, client.Client)
		}
	})

	if len(conns) == 0 {
		return nil,
			fmt.Errorf("add error inbfo %s,wrap error is %w",
				"system error", syserror.ErrGroupNotFound)
	}

	return conns, nil
}

func (gc *GroupClients) Del(clientId string) error {
	gc.withLock(func() {

		// 检查clientId是否存在
		groupName, exists := gc.ClientGroup[clientId]
		if !exists {
			return
		}

		// 删除clientId到groupName的映射
		delete(gc.ClientGroup, clientId)

		// 删除组中的客户端
		for i, client := range gc.Groups[groupName] {
			if client.ClientId == clientId {
				gc.Groups[groupName] = append(gc.Groups[groupName][:i], gc.Groups[groupName][i+1:]...)
				break
			}
		}

		// 如果组变为空，可以删除该组
		if len(gc.Groups[groupName]) == 0 {
			delete(gc.Groups, groupName)
		}
	})

	return nil
}
